

                     MDP-8008 Assembler User's Manual


                                   by

                            Ronald T. Kneusel

                                  1994



The MDP-8008 assembler was designed to ease the task of creating programs for 
the MDP-80 simulator.  This user manual describes the assembler and how to use 
it to create your own assembly language programs.  Basic knowledge of 
programming at the machine or assembler level is assumed.

This manual, the MDP-8008 assembler, MDP-80 simulator and manual, tutorials, and 
sample programs are copyright, 1994, by Ronald T. Kneusel.  Unauthorized 
reproduction or modification in any form is prohibited without prior written 
consent.

THE AUTHOR ASSUMES NO RESPONSIBILITY FOR ANY DAMAGE SUSTAINED FROM THE 
USE OF THIS PROGRAM AND MANUAL.  NO WARRANTY IS GIVEN, EITHER EXPLICITLY 
OR IMPLICITLY.  CAVEAT EMPTOR.


¥ Chapter 1  -  Introduction


In the beginning there was machine code, and it was not good.  Machine 
code is difficult to write, hard to modify, and nearly impossible to 
debug.  Life was miserable and the power of the computer was locked in the 
hands of the elite few who could manipulate the machine at its own 
level.  Enter assembly language.  Assembly language is basically a 
substitution of (relatively) easy to remember mnemonics (alphanumeric 
codes that give some indication of the purpose of an instruction) for the 
difficult to remember numerical instruction codes.  Unlike high level 
computer languages, there is a one-to-one correspondence between an 
assembly language instruction and an actual machine instruction.  Not 
only are individual machine instructions difficult to remember but the 
numerical value for a particular instruction varies from one address
mode to another.  An assembler allows the programmer to specify both an 
instruction and its address mode in an easy to read form.

The assembler described below will be of primary use to you as you work 
through the tutorials and on to creating your own programs.  This manual 
assumes a basic familiarity with assembly language programming.  If this 
is your initial attempt at assembly language it will be helpful to work 
through the tutorial first.

¥¥ Features

The MDP-8008 assembler is a fully functional, though simple, two pass assembler.  
Some of its features are listed below:

   * Free-form source code format
	
   * Unlimited source code size
	
   * Unlimited label length
	
   * Optional assembly listing and symbol table
	
   * Inclusion of useful pseudo instructions, ASC and HEX
	
   * Special address operators $>$ and $<$
	
   * Ability to include header files with standard equates


¥¥ Restrictions

In order to preserve the simple nature of the assembler some restrictions 
apply.  These are:

   * No operand arithmetic
	
   * All numbers assumed to be hexadecimal
	
   * Only a single \#ORG permitted per file
	
   * The special address operators $>$ and $<$ are restricted to labels only
	
   * All branches are assembled as absolute, not relative
	
   * All labels assemble as two bytes
	
   * Zero page instructions assembled only if address is a number



¥¥ A Sample Session


The assembler does not contain a built in text editor.  In order to 
create programs you will need some form of external text editor.  
If all else fails you can use _TeachText_ which was included with your 
Macintosh.  A standard word processor can be used provided the file is saved 
as a TEXT file.  If you are using System 7 or Multifinder, you can run both 
the assembler and your text editor and quickly switch between the two.  
This creates a rapid development environment in which changes to the source 
program can be quickly assembled and errors corrected.


¥¥¥ Creating `Hello.ASM'

Using a text editor, enter the following sample assembly language 
program and save it as `Hello.ASM'. This is the famous "Hello, world!" 
example.


;  Hello.world  -  Displays "Hello, world!"

#include std.equ    ; Standard monitor equates

#org  1000          ; Program begins at address 1000 (hexadecimal)

; Begin program

         lda >message              ; put high byte of MESSAGE in A
         ldx <message              ; put low byte of MESSAGE in X
         jsr _print                ; monitor routine to print string
         rts                       ; pointed to by A and X
.message asc 'Hello, world!'       ; here is the string
         hex 0d00                  ; 0d is return, 00 ends the string

; end



¥¥¥ Assembling `Hello.ASM'

Open the assembler application and select "Assemble File" from  the 
"File" menu.  A standard Macintosh open file dialog will appear.  Use 
it to select the file _Hello.ASM_.  The assembler will respond with 
another dialog box asking for a name to give to the assembled output file.  
Notice that the assembler has changed the .ASM suffix into .OBJ, this is 
the standard suffix for an assembled file.  Other possible suffixes 
include .LST for an assembly listing and .SYM for a symbol table.  
Clicking the _Okay_ button will cause the file to be assembled.  

During the first pass the assembler locates the labels used by 
the program.  In the second pass it generates the output file.  A `.' 
is displayed for each line of the source program that is read.  If there 
are no assembly errors it will report that assembly is complete and 
indicate the number of lines in the source file, as well as the starting and
ending memory addresses.  Errors are indicated by the corresponding line 
number in the source program.  Assuming no errors, the program is assembled 
and the file Hello.OBJ is ready to be loaded into the simulator and run.


¥¥¥ Modifying `Hello.ASM'

Suppose we want to modify our program to print the text in the middle of
a clear screen.  To accomplish this we will need to use two new subroutines, 
one in the system monitor and the other of our own design.  After the last 
line in the file include the following code:

.down    lda #0d                   ; the return character
.again   jsr _cout                 ; monitor print character routine
         dey                       ; decrease count
         bne again                 ; if not zero print again
         rts

This will print Y blank lines where Y is the current value of the Y 
register.  We will call this routine with Y set to 10 after clearing the 
screen.   After the begin program comment include the following:

         lda #0c                   ; 0C=12, clears the screen
         jsr _cout                 ; monitor routine
         ldy #0a                   ; load 10 into Y
         jsr down                  ; and call our routine

Lastly, we want to print 35 blank spaces before displaying the message.  
Fortunately, there exists a monitor routine to do this for us.  After the 
call to the subroutine _down_ enter the following:

         ldx #23                   ; X holds count
         jsr _blanks               ; print the blanks

The final modified program should appear as below:


;  Hello.world  -  Displays "Hello, world!"

#include std.equ    ; Standard monitor equates

#org  1000          ; Program begins at address 1000 (hexadecimal)

; Begin program

         lda #0c                   ; 0C=12, clears the screen
         jsr _cout                 ; monitor routine
         ldy #0a                   ; load 10 into Y
         jsr down                  ; and call our routine
         ldx #23                   ; X holds count
         jsr _blanks               ; print the blanks
         lda >message              ; put high byte of MESSAGE in A
         ldx <message              ; put low byte of MESSAGE in X
         jsr _print                ; monitor routine to print string
         rts                       ; pointed to by A and X
.message asc 'Hello, world!'       ; here is the string
         hex 0d00                  ; 0d is return, 00 ends the string
.down    lda #0d                   ; the return character
.again   jsr _cout                 ; monitor print character routine
         dey                       ; decrease count
         bne again                 ; if not zero print again
         rts

; end

Using the same procedure as before, assemble the modified file replacing 
the earlier version of `Hello.OBJ'.  Load this version into the simulator 
and run it.



¥ Chapter 2  -  The Assembler Program

The assembler is completely menu driven and is designed to be as simple 
as possible.  There are three menus: File, Edit, and Options.  The Edit 
menu is for desk accessories and is disabled. 

¥¥ The File Menu

The File menu is used to choose a file to assemble or to quit the 
application.  The first menu item `Assemble File...' will bring up a 
standard Macintosh dialog box allowing the user to select a source file 
to assemble.  If the file selected ends with `.ASM' the assembler will 
strip it before appending any other extensions.

¥¥ The Options Menu

Use the "Options" menu to select where, or if, the assembler will send 
the assembly listing or symbol table.  The currently active options are 
indicated by a checkmark.  Initially, the assembler is set for no listing 
and no symbol table.  Selecting any of the options activates it and places 
a checkmark next to it. Only one option can be active at a time.  

¥¥ The Assembly Listing

The assembly listing contains both the original source code and the 
machine code.  An assembly listing for the file `Hello.ASM' appears as, 


   1-             ;  HELLO.WORLD  -  DISPLAYS "HELLO, WORLD!"
   2-            
   3-             #INCLUDE STD.EQU  ; STANDARD MONITOR EQUATES
   4-            
   5-             #ORG  1000        ; PROGRAM BEGINS AT ADDRESS 1000 (HEX)
   6-            
   7-             ; BEGIN PROGRAM
   8-            
   9-  1000: A9 0C       LDA #0C             ; 0C=12, CLEARS THE SCREEN
  10-  1002: 20 F8 76    JSR _COUT           ; MONITOR ROUTINE
  11-  1005: A6 0A       LDY #0A             ; LOAD 10 INTO Y
  12-  1007: 20 10 26    JSR DOWN            ; AND CALL OUR ROUTINE
  13-  100A: A8 23       LDX #23             ; X HOLDS COUNT
  14-  100C: 20 FF D8    JSR _BLANKS         ; PRINT THE BLANKS
  15-  100F: A9 10       LDA >MESSAGE        ; PUT HIGH BYTE OF MESSAGE IN A
  16-  1011: A8 17       LDX <MESSAGE        ; PUT LOW BYTE OF MESSAGE IN X
  17-  1013: 20 F8 D2    JSR _PRINT          ; MONITOR ROUTINE TO PRINT STRING
  18-  1016: 60          RTS                 ; POINTED TO BY A AND X
  19-  1017: 48656C6C6F2C20776F726C6421   .MESSAGE ASC 'Hello, world!'   ; HERE IS THE STRING
  20-  1024: 0D00   HEX 0D00                 ; 0D IS RETURN, 00 ENDS THE STRING
  21-  1026: A9 0D       .DOWN    LDA #0D    ; THE RETURN CHARACTER
  22-  1028: 20 F8 76    .AGAIN   JSR _COUT  ; MONITOR PRINT CHARACTER ROUTINE
  23-  102B: C5          DEY                 ; DECREASE COUNT
  24-  102C: D1 10 28    BNE AGAIN           ; IF NOT ZERO PRINT AGAIN
  25-  102F: 60          RTS
  26-            
  27-             ; END
  28-            

The line number is followed by the actual address and machine code that 
correspond to the instruction listed.  Note that all assembler input is 
mapped to uppercase characters.  

The options concerning the assembly listing are straightforward.  The 
listing can be sent to the terminal (List to terminal), to a file 
on disk (List to file), or directly to the printer (List to printer).  
Listing directly to the printer is rather slow, so be patient.

If _List to file_ is selected the assembler will create a file with the 
same name as the source file plus a `.LST' extension.  This file is a 
standard TEXT file and has the format given above.  You can read this file 
into any text editor, though the file will have the creator 
`ALFA' and will look for the Shareware editor Alpha by Peter Keleher when 
double-clicked.  Alpha is an excellent editor and is highly recommended as 
a companion to the assembler and simulator.

¥¥¥ The Symbol Table

The symbol table is a list of the labels defined in an assembly language
program.  Labels are created in one of three ways: (1) by an #EQU 
statement, (2) by prefixing an instruction line with `.label' where 
`label' is the label that will reference that line, or (3) by using an 
#INCLUDE to include a file of equates (such as the file STD.EQU which 
contains the equates for the system monitor).  During the first pass of 
the assembler all labels are identified and the location they reference 
is determined.  The second pass then uses this information to fill in the 
proper addresses for creating the output file.

The symbol table for the program `Hello.ASM' appears as,


Symbol Table
 
[0200] KOUT        [0201] CSTB        [0202] KBDS        [0203] KEYB        
[0100] STAK        [FFFD] COLD        [FFFA] BREAK       [0300] TEXT        
[F800] _MON        [F830] VERSION     [F832] _MON1       [F851] _BRK        
[F876] _COUT       [F87D] _KEYIN      [F884] _INPUT      [F889] _INPUT1     
[F8D2] _PRINT      [F8D6] PRINT1      [F8E9] _PRINTHEX   [F920] _PRINTWORD  
[F928] _UPPER      [F92C] _UPPER1     [F952] _KILLB      [F956] _KILLB1     
[F989] _LENGTH     [F99B] _MAKEHEX    [F9C3] _MAKEBYTE   [F9DD] _NUMBER     
[F9E1] _NUMBER1    [FA50] _ADD16      [FF7F] _REG        [FFD8] _BLANKS     
[1017] MESSAGE     [1026] DOWN        [1028] AGAIN       


Note that there are far more symbols present than the few defined in the 
program itself.  This is due to the #INCLUDE STD.EQU statement which 
includes the symbols for the more important and useful system monitor 
routines.  The assembler does not differentiate between #INCLUDEd symbols 
and symbols created in the program.  The value in square brackets is the 
address associated with the symbol whose name follows.  By convention, all 
system monitor subroutines have the `_' character as the first character in 
the symbol name.  The individual subroutines are discussed in _The System 
Monitor via Assembly Language_ chapter.

Symbol table options include sending the table to the terminal (Table to 
terminal), to a file (Table to file), or to the printer (Table to printer).  
As with the assembly listing, sending the table to the printer is rather slow.

If "Table to file" is selected and there is no assembly listing or 
the listing is not being sent to a file the assembler will prompt you for 
a file name.  By default it will choose the name of the source file plus 
a `.SYM' extension.  If both "List to file" and "Table to file" are selected 
the symbol table will be automatically appended to the end of the listing file 
and no `.SYM' file will be created.


¥ Chapter 3  -  Assembler Instruction Format

An assembly language source file will contain several elements, some 
mandatory, others optional:

  *  Assembler directives
  *  Labels (or symbols)
  *  Mnemonics (instruction codes)
  *  Operands
  *  Comments and white space
  *  Special forms


¥¥ Assembler directives

The MDP-8008 assembler understands only three types of directives: 
#EQU, #ORG, and #INCLUDE.  These are not instructions but are a way 
of providing the assembler with information about the source file.  They 
typically appear near the beginning of a program before any actual 
instructions.  This is not a requirement, however, since the assembler uses
two passes the directives may appear anywhere without restriction.

¥¥ #EQU

The #EQU (equate) directive may appear anywhere and is used to bind an address 
to a symbol.  The format is:

                     #EQU   `label'   `address'

Where `label' is the symbol being defined and `address' is the address 
bound to `label'.  The symbol must begin with a letter of the alphabet or 
the `_' character, which, by convention, is reserved for system monitor 
routines. If a symbol is defined more than once an assembler warning 
error is generated and the initial binding is used.  This usually results 
in garbage when the program is run.  The address bound to the symbol must 
be a valid hexadecimal number and in the range 0000 to FFFF.

¥¥ #ORG

The #ORG (origin) directive determines the address at which to begin 
assembling the program. The format is:

                         #ORG  `address'

Where `address' must be a valid hexadecimal number in the range 0000 to 
FFFF.  If there is more than one #ORG statement in a file the last one 
read will be used as the starting address.  If no #ORG is specified the 
assembler defaults to the address 0400.

¥¥ #INCLUDE

The #INCLUDE directive specifies the name of a file that may only contain 
comments, white space, and valid #EQU statements.  The format is:

                          #INCLUDE  `file'

Where `file' is the name of the file to be included.  If no pathname is 
specified the file is assumed to be in the same folder as the assembler 
application.  #INCLUDE is useful when a series of programs will be using 
the same equates.  The assembler comes with the file STD.EQU which 
contains equates for the more useful system monitor routines.  Any number 
of #INCLUDE statements can be in a file.  The assembler will read all 
the files before proceeding further.

¥¥ Labels

Much of the power of an assembler comes from its ability to use labels 
(symbols) in place of actual addresses.  This frees the programmer to 
make alterations without concerning himself or herself with the effect on 
the rest of the program.  For the MDP-8008 assembler a label 
is defined as: any string of characters whose first character is a letter 
of the alphabet (or `_')  and does not contain any white space (spaces or 
tabs).  There is no practical limit to the length of a label.
In use, a label may be substituted anywhere an address would belong.  
When binding a label to an instruction precede it with a `.' (period):

                            lda >string
                .string     asc 'This is a string'

If the assembler encounters a multiply defined label it will use the 
value of the first binding and ignoring subsequent definitions.

¥¥ Mnemonics

Mnemonics are the three letter labels used by the assembler to represent 
the actual microprocessor instructions.  It is far easier to remember that 
LDA means to `load the accumulator' than to remember the hexadecimal 
number A9.  A complete outline of the instruction set for the MDP-8008 
microprocessor is given below.  Many instructions permit multiple addressing 
modes which the assembler indicates in the operand field.  All 
MDP-8008 mnemonics are three letters in length.  In addition to the 
actual instructions the assembler recognizes two pseudo-mnemonics, ASC 
and HEX.  These are used to assemble ASCII strings and hexadecimal data 
into a file.  Their format is described in the section on _Special forms_.

¥¥ Operands

The mnemonic determines the instruction while the operand (what the 
instruction operates on) determines the address mode.  There are seven 
possible addressing modes for the MDP-8008 and two assembler pseudo modes,
each with a different operand format.  The modes are:

  * immediate
  * implied
  * absolute
  * absolute indexed
  * indirect absolute
  * zero page
  * relative
  * > and < (pseudo)


¥¥¥ Immediate mode

Immediate mode instructions are two bytes in length and are indicated 
by a # as the first character of the operand field.  For example,

.nothing    lda #A4     ; put the value A4 into the accumulator

Note that there is no space between the # and the data.

¥¥¥ Implied mode

Implied mode is for single byte instructions that require no data.  
Indicate this to the assembler by using no operand field:

.label      tax         ; transfer the accumulator to X


¥¥¥ Absolute mode

Absolute mode instructions are three bytes in length (two bytes for an 
address) and are indicated by a `$' preceding the address value.  If a 
symbol is being used do not use a `$'.  For example,

            lda $1e39   ; load the value in $1e39 into A
            sta data    ; and put it in the address bound to `data'


¥¥¥ Absolute Indexed mode

Functionally the same as the absolute mode with the addition of the 
characters `,x' at the end of the operand field.  Example,

            lda $1e39,x  ; load the value in $1e39+X into A
            sta data,x   ; and put it in the address bound to `data'+X


¥¥¥ Indirect Absolute mode

This mode is indicated by enclosing the address in parentheses and 
appending `,x' at the end of the operand field.  Again, numerical addresses 
must be prefixed by the `$' character.  Example,

            lda ($1e39),x   ; indirect load of A
            sta (data),x    ; store indirectly


¥¥¥ Zero Page mode

The microprocessor can take advantage of the implied 00 in addresses 
below 0100.  This is called the zero page and instructions using it 
require only two bytes instead of three.  The assembler forces all labels 
to be two bytes so the only way to use zero page instructions is by 
giving a numerical address.  Zero page is indicated by a `$' as absolute 
mode is, but the address given is only two digits long:

            lda $1e     ; load the value in $1e into A


¥¥¥ Relative mode

The assembler does not directly support relative mode branching 
instructions.  All branches are assembled as absolute references.


¥¥¥ > and < pseudo modes

The special pseudo modes > and < must be used with a label, not a 
numerical address.  The > before the label is translated by the 
assembler into an immediate mode instruction whose data byte is the most 
significant byte of the address of the label.  The < translates into 
the least significant byte of the address.  Examples,

            lda >string   ; load MSB of `string' into A
            ldx <string   ; load LSB of `string' into X
.string     asc 'a string' 


¥¥¥ Comments and White Space

Comments start with a semicolon and continue to the end of the line.  Copious 
use of comments is strongly encouraged.  White space is defined as blank 
spaces or tab characters.  Blank lines are also permitted.  There must be 
at least one space or tab between the parts of a line, but leading or 
trailing white space is ignored.


¥¥¥ Special Forms

The special forms used pertain to the ASC and HEX pseudo 
instructions.  The ASC instruction expects a string of characters 
delimited by single quotes.  The HEX instruction expects a series 
of hexadecimal bytes, each of two digits (include leading zero) and with 
no spaces between them.  Examples for each are,

            asc 'this is a string'  ; use single quotes
            hex 000102030405060708  ; no spaces allowed

Both ASC and HEX are very useful for placing character data into a 
program.



¥ Chapter 4  -  The System Monitor via Assembly Language

The simulator's built in system monitor program occupies the 2K of memory 
from F800 to FFFF and contains the routines necessary to make it possible 
to enter, execute, and modify machine language programs.  It also 
contains a number of useful routines for printing strings and numbers, 
entering data, and converting strings to numbers.  The file STD.EQU which 
is included with the assembler contains equates to many of these subroutines.
#INCLUDEing this file at the beginning of your programs will make these 
routines available to you.  This chapter will discuss many of these routines, 
giving examples and noting side-effects.


                _COUT   F876   Output character in A  
  
Description: Displays the character whose ASCII code is stored in the 
             accumulator. 
Registers altered: None. 
Example:
  
lda #41    ; ASCII code for `A'
jsr _cout  ; print the letter
  


                _KEYIN   F87D   Input character from keyboard   

Description: Waits for a key to be pressed and places the ASCII value in 
             the accumulator. 
Registers altered: A. 
Example:
  
jsr _keyin    ; get a character
jsr _cout     ; and echo it back
  


               _INPUT    F87D   Input a line of text, with prompt  
               _INPUT1   F889   Input a line of text, no prompt  
   
Description: Inputs a line of text. Characters are stored starting at location 
             0300.  Backspace and delete keys work as normal. X holds the 
             length on exit. 
Registers altered: A, X. 
Example:
 
jsr _input      ; get a line of text
lda 0300        ; check first character
cmp #41         ; compare to `A'
beq Acommand    ; if so, then branch  



               _PRINT   F8D2   Print a null terminated string  
  
Description: Displays the null terminated string the address of which is in 
             A (MSB) and X (LSB). 
Registers altered: A, X. 
Example:
  
         lda >string     ; get MSB of address of string
         ldx <string     ; get LSB of address of string
         jsr _print      ; print the string
.string  asc 'a string'  ; a string
         hex 00          ; null terminates string 



              _PRINTHEX   F8E9   Print A as a hexadecimal number  
  
Description: Display the accumulator as a two digit hexadecimal number. 
Registers altered: A. 
Example:
  
         lda #2D         ; load a number
         jsr _printHex   ; displays `2D' on the screen  



          _PRINTWORD   F920   Print AX as a four digit hexadecimal number  
  
Description: Displays AX as a four digit number. A holds the high part, 
             X holds the low. 
Registers altered: A, X. 
Example:
  
         lda #33         ; load the high part
         ldx #44         ; load the low part
         jsr _printWord  ; outputs `3344'
           


             _UPPER   F928   Convert a string to uppercase  
  
Description: Converts the null terminated string starting at the address in 
             AX to uppercase. 
Registers altered: A, X. 
Example:
  
         lda >string     ; get MSB of address of string
         ldx <string     ; get LSB of address of string
         jsr _upper      ; make it uppercase
         lda >string
         ldx <string
         jsr _print      ; print the string giving `A STRING'
.string  asc 'a string'  ; a string
         hex 00          ; null terminates string  



             _KILLB   F952   Remove the blanks from a string  
  
Description: Removes the blanks from the null terminated string that starts 
             at the address in AX. 
Registers altered: A, X. 
Example:
  
         lda >string     ; get MSB of address of string
         ldx <string     ; get LSB of address of string
         jsr _killB      ; remove blanks
         lda >string
         ldx <string
         jsr _print      ; outputs 'astring'
.string  asc 'a string'  ; a string
         hex 00          ; null terminates string
  



             _LENGTH   F989   Find the length of a string  
  
Description Returns in X the length of the null terminated string pointed to 
            by 06 and 07. 
Registers altered: A, X. 
Example:
  
         lda >string     ; get MSB of address of string
         ldx <string     ; get LSB of address of string
         jsr _length     ; get length
         txa             ; put in A
         jsr _printHex   ; outputs `08'
.string  asc 'a string'  ; a string
         hex 00          ; null terminates string
 



            _NUMBER   F9DD   Convert a string to a number  
  
Description: Converts the null terminated string in AX into a 16-bit hexadecimal
             number stored in 01 and 02. 
Registers altered: A, X, and Y. 
Example:
 
        #equ text 0300   ; text input buffer
         jsr _input      ; get a number
         lda >text       
         ldx <text
         jsr _number     ; convert it
         lda $01
         ldx $02
         jsr _printWord  ; display it
  


            _REG   FF7F   Display current register values  
  
Description: Displays the current register values. 
Registers altered: None. 
Example:
  
         jsr _reg        ; output registers
  



            _BLANKS   FFD8   Output blank spaces  
  
Description: Displays blank spaces, count in X. 
Registers altered: A, X. 
Example:
  
         ldx #0D         ; set up for 13 blanks
         jsr _blanks     ; and print them



¥ Chapter 5  -  Glossary



Accumulator - is the register that the microprocessor uses for math 
and logic functions.
  
Address mode - refers to the way in which a particular microprocessor 
instruction uses the computer's memory.  The MDP-8008 has seven possible 
address modes though not all modes are available to each instruction. 
 
ASCII - stands for American Standard Code for Information 
Interchange. It is a method for coding the alphabet and other symbols in 
a machine usable form.  The letter `A' has an ASCII value of 65. 
 
Assembler - translates programs written using mnemonics and labels into 
pure machine code for use by the microprocessor.  

Bit - is the smallest unit of information a computer can use.  It is 
a single binary digit, 0 or 1, on or off.  

Byte - is a series of 8 bits and is the smallest unit of memory for 
most computers.  A single ASCII character occupies one byte of memory. 
 
Equate - binds a symbol to an address.  It is similar to defining a 
constant in other programming languages.  For example, "#equ  start  
0400" will bind the symbol `start' to the address 0400. 
 
Hexadecimal - Base 16 number system.  Digits range from 0 through 9 and 
A through F with A=10 and F=15.  Most machine code programming is 
done in hexadecimal.  The MDP-8008 assembler assumes all numbers to be 
hexadecimal.
  
Include file - is a file containing equates that may be included in 
an assembly language program.  The file STD.EQU is included with the 
assembler and contains equates for useful monitor subroutines.
 
Label - is a character string associated with a machine address.  It 
is identical in meaning to _symbol_.
 
List file - holds the assembly listing.  The listing gives the 
assembled code along with the original source and optionally includes the 
symbol table.
 
Machine code - is the native tongue of a microprocessor.  It is 
purely numerical and is generally represented as hexadecimal numbers.
 
MDP-80 - is the name of the microcomputer simulator that runs 
programs written in MDP-8008 machine code.
 
MDP-8008 - is the microprocessor for which the assembler generates 
machine code.  It is the heart of the MDP-80 microcomputer simulator.
 
Monitor - is the program burned into the ROM of a microcomputer.  It 
lets the user modify memory and run machine language programs.
 
Object file - is the output from the assembler. It contains machine 
code in a format that is usable by the simulator.
 
Pseudo instructions - are instructions that while not part of the 
actual microprocessor instruction set are simulated by the assembler.  
The ASC and HEX instructions are pseudo instructions.
 
Register - is a single byte storage space on the microprocessor.  The 
MDP-8008 has three user registers, the accumulator (A), the X, and Y.
 
Simulator - is the program that simulates the operations of a small 
microcomputer.  
 
Source file - is the file that contains the assembly language 
program. It is used by the assembler to generate the object file.
 
Symbol - see label above.
 
Symbol table - is a list of all of the symbols used in a particular 
program and the address bound to that symbol.
 
Word - is the standard unit used by a particular microprocessor.  An 
8-bit microprocessor uses one byte words.  A 32-bit microprocessor uses 4 
byte words.  In the assembler and simulator, a word generally refers to a 
16-bit, or 2 byte, value.


¥ Chapter 6  -  MDP-8008 Reference

The MDP-8008 microprocessor has 52 instructions and 7 addressing modes.  
A summary of the MDP-8008 instruction set is given in the Simulator User's
Manual.

¥¥ MDP-8008 addressing modes

An instruction's addressing mode determines the way in which the 
instruction will access and use memory.  The seven modes supported by the 
MDP-8008 are implied, immediate, absolute, absolute indexed, zero page, 
relative, and indirect indexed.

 Implied addressing 

The implied address in implied addressing is the accumulator.  Implied 
mode is used by single byte instructions that only act on the accumulator 
and do not reference memory.

 Immediate addressing 

The value used in immediate mode addressing is the next byte of the 
program, or the first operand.  The target of the instruction is one of 
the microprocessor's registers.  For example, LDA #FF loads the 
accumulator with the immediate value FF.  

 Absolute addressing

An 8-bit microprocessor like the MDP-8008 can access a total of 65536 
memory locations.  It therefore takes two bytes to represent the address 
of any memory location.  Absolute addressing uses two operand bytes (the 
first two bytes of the program following the byte containing the opcode) 
to represent the address of a memory location.  For example, STA $1E37 will 
store the contents of the accumulator in memory location 1E37.

 Absolute indexed addressing

Similar to absolute addressing, absolute indexed addressing uses as a 
target address the value obtained when the address represented by the 
operand bytes is added to the current value of the X register.  If the X 
register contains 14 and the instruction is STA $1E38,X the contents of the 
accumulator will be stored in location 1E38 + 14 = 1E4C.  Absolute indexed 
addressing is particularly useful when dealing with lists.

 Indirect indexed addressing

The target address in indirect index addressing is found by taking the 
absolute address in the operands, reading the two byte address that 
starts at the given address and adding the contents of the X register to 
get the final address.  For example, suppose the instruction being 
executed (in assembly form) is LDA ($2E33),X.  If the values stored 
in memory locations 2E33 and 2E34 are 14 and 1C and the current value of 
the X register is A4 then the accumulator will be loaded with the contents 
of location 141C + A4 = 14C0.

 Zero page addressing 

Zero page addressing takes advantage of the fact that the first 256 
memory locations can be addressed in a single byte (00 to FF).
Therefore, all instructions using the zero page are only two bytes long, 
which can add up to a significant savings if frequently used locations 
are in the zero page.

 Relative addressing 

Only the branch instructions use relative addressing.  Instead of 
specifying an absolute location in memory, a relative address is a 
positive or negative offset from the current address.  The use of 
relative addressing allows one to write code that will run at any 
location in memory.  Relative addressing uses one operand and as a result 
can reference locations that are -128 to +127 bytes from the current 
location.  The MDP-8008 assembler does not support relative addressing.


¥¥ MDP-8008 instruction names


Label  Name
--------------------------------------
 ADC   Add to accumulator with carry               
 AND   AND accumulator with memory                 
 BCC   Branch on carry clear                       
 BCS   Branch on carry set                         
 BEQ   Branch on equal or zero                     
 BGT   Branch on greater than                      
 BLT   Branch on less than                         
 BNE   Branch on not equal or not zero             
 BNG   Branch on negative set                      
 BPL   Branch on positive (not negative)           
 BRA   Unconditional relative branch               
 BRK   Break                                       
 CLC   Clear carry flag                            
 CMP   Compare accumulator to memory               
 CPX   Compare X register to memory                
 CPY   Compare Y register to memory                
 DCA   Decrement accumulator by one                
 DEC   Decrement memory by one                     
 DEX   Decrement X register by one                 
 DEY   Decrement Y register by one                 
 EOR   Exclusive-OR accumulator with memory        
 INA   Increment accumulator by one                
 INC   Increment memory by one                     
 INX   Increment X register by one                 
 INY   Increment Y register by one                 
 JMP   Jump to address                             
 JSR   Jump to subroutine at address               
 LDA   Load the accumulator with memory            
 LDX   Load the X register with memory             
 LDY   Load the Y register with memory             
 LSH   Bit shift accumulator left, no carry        
 NOP   No operation                                
 ORA   OR accumulator with memory                  
 PHA   Push accumulator on stack                   
 PHP   Push processor status on stack              
 PLA   Pull accumulator from stack                 
 PLP   Pull processor status from stack            
 ROL   Rotate accumulator to the left with carry   
 ROR   Rotate accumulator to the right with carry  
 RSH   Bit shift accumulator right, no carry       
 RTS   Return from subroutine                      
 SBC   Subtract memory from accumulator with carry 
 SEC   Set carry flag                              
 STA   Store accumulator in memory at address      
 STX   Store X register in memory at address       
 STY   Store Y register in memory at address       
 TAX   Transfer accumulator to X register          
 TAY   Transfer accumulator to Y register          
 TSX   Transfer stack pointer to X register        
 TXA   Transfer X register to accumulator          
 TXS   Transfer X register to stack pointer        
 TYA   Transfer Y register to accumulator          
 
